home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / rewrite / RewriteManip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-18  |  7.9 KB  |  343 lines

  1. /*
  2.  * $Header: /private/postgres/src/rewrite/RCS/RewriteManip.c,v 2.19 1992/08/03 23:28:46 glass Exp $
  3.  */
  4.  
  5. #include "nodes/pg_lisp.h"
  6. #include "tmp/c.h"
  7. #include "utils/log.h"
  8. #include "nodes/nodes.h"
  9. #include "nodes/relation.h"
  10. #include "rules/prs2locks.h"        /* prs2 lock definitions */
  11. #include "rules/prs2.h"            /* prs2 routine headers */
  12. #include "nodes/primnodes.h"
  13. #include "nodes/primnodes.a.h"
  14. #include "parser/parsetree.h"
  15. #include "parser/parse.h"
  16. #include "utils/lsyscache.h"
  17. #include "./RewriteHandl.h"
  18. #include "./RewriteSuppo.h"
  19. #include "./locks.h"
  20.  
  21. #include "nodes/plannodes.h"
  22. #include "nodes/plannodes.a.h"
  23.  
  24.  
  25. extern List copy_seq_tree();
  26. extern Const RMakeConst();
  27. extern List lispCopy();
  28.  
  29.  
  30. void
  31. OffsetVarNodes ( qual_or_tlist , offset ) 
  32.      List qual_or_tlist;
  33.      int offset;
  34. {
  35.     List i = NULL;
  36.  
  37.     foreach ( i , qual_or_tlist ) {
  38.     Node this_node = (Node)CAR(i);
  39.     if ( this_node ) {
  40.         switch ( NodeType (this_node)) {
  41.           case classTag(LispList):
  42.         OffsetVarNodes ( (List)this_node , offset );
  43.         break;
  44.           case classTag(Var): {
  45.           int this_varno = (int)get_varno ( (Var) this_node );
  46.           int new_varno = this_varno + offset;
  47.           set_varno ( (Var) this_node , new_varno );
  48.           CAR(get_varid ( (Var) this_node)) = 
  49.             lispInteger ( new_varno );
  50.           break;
  51.           }
  52.           default:
  53.         /* ignore the others */
  54.         break;
  55.         } /* end switch on type */
  56.     } /* if not null */
  57.     } /* foreach element in subtree */
  58. }
  59. void
  60. ChangeVarNodes ( qual_or_tlist , old_varno, new_varno)
  61.      List qual_or_tlist;
  62.      int old_varno, new_varno;
  63. {
  64.     List i = NULL;
  65.  
  66.     foreach ( i , qual_or_tlist ) {
  67.     Node this_node = (Node)CAR(i);
  68.     if ( this_node ) {
  69.         switch ( NodeType (this_node)) {
  70.           case classTag(LispList):
  71.           ChangeVarNodes ( (List)this_node , old_varno, new_varno);
  72.         break;
  73.           case classTag(Var): {
  74.           int this_varno = (int)get_varno ( (Var) this_node );
  75.           if (this_varno == old_varno) {
  76.               set_varno ((Var) this_node, new_varno);
  77.               CAR(get_varid ( (Var) this_node)) = 
  78.               lispInteger ( new_varno );
  79.           }
  80.           break;
  81.           }
  82.           default:
  83.         /* ignore the others */
  84.         break;
  85.         } /* end switch on type */
  86.     } /* if not null */
  87.     } /* foreach element in subtree */
  88. }
  89.  
  90. void AddQual(parsetree, qual)
  91. List parsetree,qual;
  92. {
  93.     List copy,old;
  94.  
  95.     if (qual == NULL) return;
  96.  
  97.     copy = copy_seq_tree (qual);
  98.     old = parse_qualification(parsetree);
  99.     if (old == NULL)
  100.     parse_qualification(parsetree) = copy;
  101.     else 
  102.     parse_qualification(parsetree) = 
  103.         lispCons(lispInteger(AND),
  104.              lispCons(parse_qualification(parsetree),
  105.                   lispCons(copy,LispNil)));
  106. }
  107. void AddNotQual(parsetree, qual)
  108. List parsetree,qual;
  109. {
  110.     List copy,old;
  111.  
  112.     if (qual == NULL) return;
  113.  
  114.     copy = lispCons(lispInteger(NOT),
  115.             lispCons(copy_seq_tree(qual), LispNil));
  116.     AddQual(parsetree,copy);
  117. }
  118.  
  119. static List make_null(type)
  120.      ObjectId type;     
  121. {
  122.     Const c;
  123.     
  124.     c = RMakeConst();
  125.     set_consttype(c, type);
  126.     set_constlen(c, (Size) get_typlen(type));
  127.     set_constvalue(c, PointerGetDatum(NULL));
  128.     set_constisnull(c, true);
  129.     set_constbyval(c, get_typbyval(type));
  130.     return lispCons((LispValue)c,LispNil);
  131. }
  132. void FixResdomTypes (user_tlist)
  133.      List user_tlist;
  134. {
  135.     List i;
  136.     foreach ( i , user_tlist ) {
  137.     List one_entry = CAR(i);
  138.     List entry_LHS  = CAR(one_entry);
  139.     List entry_RHS = CAR(CDR(one_entry));
  140.     
  141.     Assert(IsA(entry_LHS,Resdom));
  142.     if (NodeType(entry_RHS) == classTag(Var)) {
  143.         set_restype((Resdom) entry_LHS,
  144.             get_vartype((Var) entry_RHS));
  145.         set_reslen ((Resdom) entry_LHS,
  146.             get_typlen(get_vartype((Var) entry_RHS)));
  147.     }
  148.     }
  149. }
  150.  
  151. static List 
  152. FindMatchingNew ( user_tlist , attno )
  153.      List user_tlist;
  154.      int attno;
  155. {
  156.     List i = LispNil;
  157.     
  158.     foreach ( i , user_tlist ) {
  159.     List one_entry = CAR(i);
  160.     List entry_LHS  = CAR(one_entry);
  161.     
  162.     Assert(IsA(entry_LHS,Resdom));
  163.     if ( get_resno((Resdom) entry_LHS) == attno ) {
  164.         return ( CDR(one_entry));
  165.     }
  166.     }
  167.     return LispNil; /* could not find a matching RHS */
  168. }
  169. static List 
  170. FindMatchingTLEntry ( user_tlist , e_attname)
  171.      List user_tlist;
  172.      Name e_attname;
  173. {
  174.     List i = LispNil;
  175.     
  176.     foreach ( i , user_tlist ) {
  177.     List one_entry = CAR(i);
  178.     List entry_LHS  = CAR(one_entry);
  179.     Name foo;
  180.     Resdom x;
  181.     Assert(IsA(entry_LHS,Resdom));
  182.     x = (Resdom) entry_LHS;    
  183.     foo = get_resname((Resdom) entry_LHS);
  184.     if (!strcmp(foo, e_attname))
  185.         return ( CDR(one_entry));
  186.     }
  187.     return LispNil ; /* could not find a matching RHS */
  188. }
  189.     
  190. void ResolveNew(info, targetlist,tree)
  191. RewriteInfo *info;
  192. List targetlist;
  193. List tree;
  194. {
  195.     List i,n;
  196.  
  197.     foreach ( i , tree) {
  198.     List this_node = CAR(i);            
  199.     if ( this_node ) {
  200.         switch ( NodeType (this_node)) {
  201.         case classTag(LispList):
  202.         ResolveNew (info, targetlist,  (List)this_node);
  203.         break;
  204.         case classTag(Var): {
  205.         int this_varno = (int)get_varno ( (Var) this_node );
  206.         if ((this_varno == info->new_varno) ) {
  207.             n = FindMatchingNew (targetlist ,
  208.                      get_varattno((Var) this_node));
  209.             if (n == LispNil) {
  210.             if (info->event    == REPLACE) {
  211.                 set_varno((Var) this_node, info->current_varno);
  212.             }
  213.             else {
  214.                 n = (List) make_null(get_vartype((Var) this_node));
  215.                 CAR(i) = CAR(n);
  216. /*                CDR(i) = CDR(n);*/
  217.             }
  218.             }
  219.             else {
  220.             CAR(i) = CAR(n);
  221. /*            CDR(i) = CDR(n);*/
  222.             }
  223.         }
  224.         break;
  225.         }
  226.         default:
  227.         /* ignore the others */
  228.         break;
  229.         } /* end switch on type */
  230.     } /* foreach element in subtree */
  231.     }
  232. }
  233.  
  234. void FixNew(info, parsetree)
  235. List parsetree;
  236. RewriteInfo *info;
  237. {
  238.     
  239. /*    if ((info->action == DELETE) || (info->action == RETRIEVE))    return;*/
  240.     ResolveNew(info,parse_targetlist(parsetree),info->rule_action);
  241. }
  242. /* 
  243.  * Handles 'on retrieve to relation.attribute
  244.  *          do instead retrieve (attribute = expression) w/qual'
  245.  */
  246. void HandleRIRAttributeRule(parsetree, rt,tl, rt_index, attr_num,modified,
  247.                 badpostquel)
  248.      List rt;
  249.      List parsetree, tl;
  250.      int  rt_index, attr_num,*modified,*badpostquel;
  251. {
  252.     List entry, entry_LHS;
  253.     List i,n;
  254.  
  255.     foreach ( i , parsetree) {
  256.     List this_node = CAR(i);
  257.     if ( this_node ) {
  258.         switch ( NodeType (this_node)) {
  259.         case classTag(LispList):
  260.         HandleRIRAttributeRule(this_node, rt,tl, rt_index, attr_num,
  261.                        modified,badpostquel);
  262.         break;
  263.         case classTag(Var): {
  264.         int this_varno = (int)get_varno ( (Var) this_node );
  265.         char *name_to_look_for = NULL;
  266.         if (this_varno == rt_index &&
  267.             get_varattno((Var) this_node) == attr_num) {
  268.             if (get_vartype((Var) this_node) == 32) { /* HACK */
  269.                 n = (List) make_null(get_vartype((Var) this_node));
  270.                 CAR(i) = CAR(n);
  271.                 *modified = TRUE;
  272.                 *badpostquel = TRUE;
  273.                 break;
  274.             }
  275.             else {
  276.                 name_to_look_for = (char *)
  277.                 get_attname(CInteger(getrelid(this_varno,
  278.                                   rt)),
  279.                         attr_num);
  280.             }
  281.             }
  282.         if (name_to_look_for) {
  283.             n = FindMatchingTLEntry(tl,name_to_look_for);
  284.             if (n == NULL)
  285.             n = (List) make_null(get_vartype((Var) this_node));
  286.             CAR(i) = CAR(n);
  287.             *modified = TRUE;
  288.         }
  289.         break;
  290.         }
  291.         default:
  292.         /* ignore the others */
  293.         break;
  294.         } /* end switch on type */
  295.     } /* foreach element in subtree */
  296.     }
  297. }
  298.  
  299.  
  300. void HandleViewRule(parsetree, rt,tl, rt_index,modified)
  301.      List parsetree, tl,rt;
  302.      int  rt_index,*modified;
  303. {
  304.     List i,n;
  305.  
  306.     foreach ( i , parsetree) {
  307.     List this_node = CAR(i);
  308.     if ( this_node ) {
  309.         switch ( NodeType (this_node)) {
  310.         case classTag(LispList):
  311.         HandleViewRule((List) this_node, rt, tl, rt_index,modified);
  312.         break;
  313.         case classTag(Var): {
  314.         int this_varno = (int)get_varno ( (Var) this_node );
  315.         if (this_varno == rt_index) {
  316.             Var x = (Var) this_node;
  317.  
  318.             n = FindMatchingTLEntry
  319.             (tl,
  320.              get_attname(CInteger(getrelid(this_varno,rt)),
  321.                      get_varattno(x)));
  322.              if (n == NULL)
  323.             n = (List) make_null(get_vartype((Var) this_node));
  324.             CAR(i) = CAR(n);
  325. /*            CDR(i) = CDR(n);*/
  326.             *modified = TRUE;
  327.         }
  328.         }
  329.         break;
  330.         default:
  331.         /* ignore the others */
  332.         break;
  333.         } /* end switch on type */
  334.     } /* foreach element in subtree */
  335.     }
  336. }
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.